package com.dnjn.mes.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dnjn.mes.biz.assist.RecordTaskHandler;
import com.dnjn.mes.biz.domain.MesRegisterAddress;
import com.dnjn.mes.biz.enums.AddrCode;
import com.dnjn.mes.biz.enums.AddrType;
import com.dnjn.mes.biz.mapper.MesRegisterAddressMapper;
import com.dnjn.mes.biz.service.IMesEquipmentService;
import com.dnjn.mes.biz.service.IMesRegisterAddressService;
import com.dnjn.mes.common.exception.job.TaskException;
import com.dnjn.mes.common.utils.CountModbusAddrUtil;
import com.dnjn.mes.quartz.domain.SysJob;
import com.dnjn.mes.quartz.service.ISysJobService;
import com.dnjn.mes.system.service.impl.SysUserServiceImpl;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Pattern;

import static com.dnjn.mes.common.utils.SecurityUtils.getUsername;

/**
 * <p>
 * modbus地址对应表 服务实现类
 * </p>
 *
 * @author Amber
 * @since 2023-07-26
 */
@Service
public class MesRegisterAddressServiceImpl extends ServiceImpl<MesRegisterAddressMapper, MesRegisterAddress> implements IMesRegisterAddressService {

    private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class);
    private static final ConcurrentMap<String, Object> concurrentHashMap = new ConcurrentHashMap<>();
    private static final String CAPACITYTIMER = "CAPACITYTIMER";
    private static final String BEATTIMER = "BEATTIMER";

    @Autowired
    private ISysJobService jobService;
    @Autowired
    private RecordTaskHandler recordTaskHandler;
    @Autowired
    private IMesEquipmentService equipmentService;

    //项目启动时执行该方法，查询节拍信息启动定时器。
    @PostConstruct
    private void queryBeatDuration(){
        Long equipmentId = equipmentService.fetchCurrent().getEquipmentId();
        QueryWrapper<MesRegisterAddress> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("equipment_id",equipmentId);
        queryWrapper.eq("addr_code","BEAT");
        MesRegisterAddress mesRegisterAddress = baseMapper.selectOne(queryWrapper);
        if (null != mesRegisterAddress){
            Timer timer = new Timer();
            timer.scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {
                    LocalDateTime dateTime = LocalDateTime.now();
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss SSS");
                    String format = dateTime.format(formatter);
                    log.info("项目启动成功，节拍定时任务执行");
                    recordTaskHandler.handleBeat();
                }
            }, 1000, mesRegisterAddress.getDuration());
            concurrentHashMap.put(BEATTIMER, timer);
        }
    }

    @Override
    public List<MesRegisterAddress> fetchCurrentAddress() {
        return baseMapper.fetchCurrentAddress();

    }

    @Override
    public MesRegisterAddress fetchAddressByAddrCode(AddrCode addrCode, Long equipmentId) {
        return baseMapper.fetchAddressByAddrCode(addrCode);
    }

    @Override
    public List<MesRegisterAddress> fetchAddressByAddrType(AddrType addrType) {
        return baseMapper.fetchAddressByAddrType(addrType);
    }

    @Override
    @Transactional
    public Boolean updateAddressByCode(MesRegisterAddress mesRegisterAddress) {


        //判断是否产量 CAPACITY，节拍 BEAT
        if ("CAPACITY".equals(mesRegisterAddress.getAddrCode().getName()) && !Objects.isNull(
                mesRegisterAddress.getDuration())) {
            //根据间隔动态执行定时任务
            Timer timer = (Timer) concurrentHashMap.get(CAPACITYTIMER);
            if (null != timer) {
                timer.cancel();
            }

            timer = new Timer();
            timer.scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {
                    LocalDateTime dateTime = LocalDateTime.now();
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss SSS");
                    String format = dateTime.format(formatter);
                    log.info("产能间隔修改，产能定时任务变更执行");
//                    System.out.println(format);
//                    System.out.println("----------------任务1执行-------------------");
                    //recordTaskHandler.handleCapacity();
                }
            }, 1000, mesRegisterAddress.getDuration());
            concurrentHashMap.put(CAPACITYTIMER, timer);
            //生成七子表达式，存入job
            /*String endStr = "* * * * ?";
            String startStr = "0/" + mesRegisterAddress.getDuration() + " ";
            String cornStr = startStr + endStr;
            SysJob sysJob = new SysJob();
            sysJob.setJobName("产量间隔");
            sysJob.setJobGroup("handleCapacity");
            sysJob.setInvokeTarget("recordTask.handleCapacity");
            sysJob.setCronExpression(cornStr);
            sysJob.setCreateBy(getUsername());
            sysJob.setMisfirePolicy("3");
            try {
                SysJob job = new SysJob();
                job.setJobGroup("handleCapacity");
                List<SysJob> sysJobList = jobService.selectJobList(job);
                if (sysJobList.isEmpty()) {//不存在，新增
                    jobService.insertJob(sysJob);
                    SysJob newJob = jobService.selectJobById(sysJob.getJobId());
                    newJob.setStatus("0");
                    jobService.changeStatus(newJob);
                } else {//存在，更新
                    sysJob.setJobId(sysJobList.get(0).getJobId());
                    sysJob.setStatus("0");
                    jobService.updateJob(sysJob);
                }

            } catch (SchedulerException e) {
                e.printStackTrace();
                return false;
            } catch (TaskException e) {
                e.printStackTrace();
                return false;
            }*/
        }
        if ("BEAT".equals(mesRegisterAddress.getAddrCode().getName()) && !Objects.isNull(
                mesRegisterAddress.getDuration())) {
            //根据间隔动态执行定时任务
            //根据间隔动态执行定时任务
            Timer timer = (Timer) concurrentHashMap.get(BEATTIMER);
            if (null != timer) {
                timer.cancel();
            }
            timer = new Timer();
            timer.scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {
                    LocalDateTime dateTime = LocalDateTime.now();
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss SSS");
                    String format = dateTime.format(formatter);
                    log.info("节拍间隔修改，节拍定时任务变更执行");
//                    System.out.println(format);
//                    System.out.println("=====================任务2执行========================");
                    recordTaskHandler.handleBeat();
                }
            }, 1000, mesRegisterAddress.getDuration());
            concurrentHashMap.put(BEATTIMER, timer);
            //生成七子表达式，存入job
            /*String endStr = "* * * * ?";
            String startStr = "0/" + mesRegisterAddress.getDuration() + " ";
            String cornStr = startStr + endStr;
            SysJob sysJob = new SysJob();
            sysJob.setJobName("节拍间隔");
            sysJob.setJobGroup("handleBeat");
            sysJob.setInvokeTarget("recordTask.handleBeat");
            sysJob.setCronExpression(cornStr);
            sysJob.setCreateBy(getUsername());
            sysJob.setMisfirePolicy("3");
            try {
                SysJob job = new SysJob();
                job.setJobGroup("handleBeat");
                List<SysJob> sysJobList = jobService.selectJobList(job);
                if (sysJobList.isEmpty()) {//不存在，新增
                    jobService.insertJob(sysJob);
                    SysJob newJob = jobService.selectJobById(sysJob.getJobId());
                    newJob.setStatus("0");
                    jobService.changeStatus(newJob);
                } else {//存在，更新
                    sysJob.setJobId(sysJobList.get(0).getJobId());
                    sysJob.setStatus("0");
                    jobService.updateJob(sysJob);
                }

            } catch (SchedulerException e) {
                e.printStackTrace();
                return false;
            } catch (TaskException e) {
                e.printStackTrace();
                return false;
            }*/
        }
        //处理modbus地址
        if (mesRegisterAddress != null) {
            Integer addrModbus = mesRegisterAddress.getAddrModbus();
            log.info(mesRegisterAddress.getAddrPlc() + "addrModbus地址：======================" + addrModbus);
            if (Objects.isNull(addrModbus)) { // ？判断是否正确
                String addrPlc = mesRegisterAddress.getAddrPlc();
                Integer modbusAddr = CountModbusAddrUtil.getRegisterModbusAddrByPlcAddr(addrPlc);
                mesRegisterAddress.setAddrModbus(modbusAddr);
            }
        }
        return baseMapper.updateAddressByCode(mesRegisterAddress);
    }


}
